package miku.firstgame.ui.card
{
	import com.saia.starlingPunk.SPEntity;
	import com.saia.starlingPunk.SPMask;

	import flash.geom.Point;
	import flash.media.Video;
	import flash.utils.Dictionary;

	import miku.firstgame.entity.Bomb;
	import miku.firstgame.model.gold.card.BombCard;
	import miku.firstgame.model.gold.card.Card;
	import miku.firstgame.model.gold.card.CardCanPassPosition;
	import miku.firstgame.model.gold.card.EndCard;
	import miku.firstgame.model.gold.card.GoldCardType;
	import miku.firstgame.model.gold.card.MapCard;
	import miku.firstgame.model.gold.card.RoadCard;
	import miku.firstgame.model.gold.interfaces.ICard;
	import miku.firstgame.model.gold.util.CardUtil;

	import starling.core.Starling;
	import starling.display.Quad;
	import starling.events.Event;

	public class CardMap extends SPEntity
	{
		private var back:Quad;

		private var cards:Vector.<RoadCardUI>;

		/**
		 * 开放列表
		 * */
		private var _open:Vector.<RoadCardUI>;
		/**
		 * 关闭列表
		 * */
		private var _closed:Vector.<RoadCardUI>;

		/**
		 * 搜索到的最短路径
		 * */
		private var _path:Vector.<RoadCardUI>;

		/**
		 * 卡牌移动刀地图上的感应区域
		 * */
		private var validateArea:ValidateCardArea;

		private var end1:EndCard;
		private var end2:EndCard;
		private var end3:EndCard;

		public function CardMap(x:Number = 0, y:Number = 0, type:String = "cardMap", mask:SPMask = null)
		{
			super(x, y, type, mask);
			initCard();
			initSearch();
		}

		private function initCard():void
		{
			cards = new Vector.<RoadCardUI>;
			for (var i:int = 0; i < 45; i++)
			{
				cards.push(null);
			}
		}

		private function initSearch():void
		{
			_open = new Vector.<RoadCardUI>();
			_closed = new Vector.<RoadCardUI>();
		}

		private function clearPath():void
		{
			if (_path)
			{
				for each (var card:RoadCardUI in _path)
				{
					card.selected = false;
				}
			}
		}

		override public function added():void
		{
			super.added();
			back = new Quad(CardUI.WIDTH * 9, CardUI.HEIGHT * 5, 0xaaaaaa);
			addChildAt(back, 0);
			setupGraphic();
		}

		protected function setupGraphic():void
		{
			validateArea = new ValidateCardArea();
			validateArea.visible = false;
			addChild(validateArea);
		}

		/**
		 * 根据xy坐标获取卡片的位置
		 * */
		public function getPositionByXY(x:Number, y:Number):Point
		{
			var result:Point = new Point();
			result.x = Math.floor(x / CardUI.WIDTH);
			result.y = Math.floor(y / CardUI.HEIGHT);
			return result;
		}

		/**
		 * 5行9列
		 * */
		public function getCardByPosition(x:Number, y:Number):RoadCardUI
		{
			return cards[x * 5 + y];
		}

		/**
		 * 根据坐标设置卡片位置
		 * */
		public function setCardPosition(card:Card, x:Number, y:Number, toggle:Boolean = false):RoadCardUI
		{
//			var point:Point = getPositionByXY(x, y);
			var cardUI:RoadCardUI = CardUtil.getCardUIByCard(card) as RoadCardUI;
			if (cardUI)
			{
				setCardUiPosition(cardUI, x, y);
				return cardUI;
			}
			return null
		}

		public function setCardUiPosition(cardUI:RoadCardUI, x:Number, y:Number):void
		{
			cardUI.x = x * CardUI.WIDTH;
			cardUI.y = y * CardUI.HEIGHT;
			cardUI.cellX = x;
			cardUI.cellY = y;
			cards[x * 5 + y] = cardUI;
			addChild(cardUI);
//			cardUI.addEventListener(Event.ADDED, onEvent);
//			cardUI.addEventListener(Event.REMOVED, onEvent);
//			cardUI.addEventListener(Event.ADDED_TO_STAGE, onEvent);
//			cardUI.addEventListener(Event.REMOVED_FROM_STAGE, onEvent);

//			Starling.juggler.delayCall(delayCall, 5, cardUI);

		}

//		private function onEvent(e:Event):void
//		{
//			trace(e.type);
//		}
//
//		private function delayCall(card:CardUI):void
//		{
//			trace("delayCall");
//		}

		override public function removed():void
		{
			removeChildren(0, -1, true);
			super.removed();
		}

		override public function update():void
		{
			super.update();

		}

		/**
		 * 表示该路径卡片是否能够被放下
		 * */
		public function canConnect(card:RoadCard, x:int, y:int):Boolean
		{
			return canConnectTo(CardCanPassPosition.BOTTOM
				| CardCanPassPosition.RIGHT | CardCanPassPosition.LEFT
				| CardCanPassPosition.TOP, card, x, y);

		}

		/**
		 * 不包括出界的情况
		 *是否能够连接到card的某个方向
		 * @param direct
		 * @param card
		 * @param x
		 * @param y
		 * @return
		 */
		public function canConnectTo(direct:int, card:RoadCard, x:int, y:int):Boolean
		{
			var connectOtherCard:Boolean = false;

			if ((direct & CardCanPassPosition.TOP) == CardCanPassPosition.TOP)
			{
				if (y > 0)
				{
					var top:RoadCardUI = getCardByPosition(x, y - 1);
					if (top != null)
					{
						connectOtherCard = true;
						if (((top.passPosition & CardCanPassPosition.BOTTOM) == CardCanPassPosition.BOTTOM)
							!= ((card.passPosition & CardCanPassPosition.TOP) == CardCanPassPosition.TOP))
						{
							return false;
						}
					}
				}
			}

			if ((direct & CardCanPassPosition.LEFT) == CardCanPassPosition.LEFT)
			{
				if (x > 0)
				{
					var left:RoadCardUI = getCardByPosition(x - 1, y);
					if (left != null)
					{
						connectOtherCard = true;
						if (((left.passPosition & CardCanPassPosition.RIGHT) == CardCanPassPosition.RIGHT)
							!= ((card.passPosition & CardCanPassPosition.LEFT) == CardCanPassPosition.LEFT))
						{
							return false;
						}
					}
				}
			}
			if ((direct & CardCanPassPosition.BOTTOM) == CardCanPassPosition.BOTTOM)
			{
				if (y < 4)
				{
					var bottom:RoadCardUI = getCardByPosition(x, y + 1);
					if (bottom != null)
					{
						connectOtherCard = true;
						if (((bottom.passPosition & CardCanPassPosition.TOP) == CardCanPassPosition.TOP)
							!= ((card.passPosition & CardCanPassPosition.BOTTOM) == CardCanPassPosition.BOTTOM))
						{
							return false;
						}
					}
				}
			}
			if ((direct & CardCanPassPosition.RIGHT) == CardCanPassPosition.RIGHT)
			{
				if (x < 8)
				{
					var right:RoadCardUI = getCardByPosition(x + 1, y);
					if (right != null)
					{
						connectOtherCard = true;
						if (((right.passPosition & CardCanPassPosition.LEFT) == CardCanPassPosition.LEFT)
							!= ((card.passPosition & CardCanPassPosition.RIGHT) == CardCanPassPosition.RIGHT))
						{
							return false;
						}
					}
				}
			}
			return connectOtherCard;
		}

		/**
		 * 表示某卡片是否能够放下，炸弹卡也可以放下,不过会删除卡片
		 * */
		public function canPlace(card:ICard, x:int, y:int):Boolean
		{
			if ((x == 0 && y == 2))
			{
				return false;
			} // 终点和起始点

			var targetCard:RoadCardUI = getCardByPosition(x, y);

			if (card is BombCard)
			{
				if (targetCard != null)
				{
					return true;
				}
			}
			else if (card is MapCard)
			{
				if ((x == 8 && y == 0) || (x == 8 && y == 2)
					|| (x == 8 && y == 4))
				{
					return true;
				}
			}
			else if (card is RoadCard && null == targetCard)
			{
				var r:RoadCard = card as RoadCard;
				return canConnect(r, x, y);
			}
			return false;
		}

		/**
		 * 某张卡片是否能到达指定的点
		 *
		 * card目标卡片
		 * point目标点
		 * */
		public function isReachPoint(cardUI:RoadCardUI, card:RoadCard, point:Point):Boolean
		{
			if (cardUI.cellX - 1 == point.x && cardUI.cellY == point.y)
			{
				if ((cardUI.passPosition & CardCanPassPosition.LEFT) == CardCanPassPosition.LEFT)
				{

					if ((card.passPosition & CardCanPassPosition.RIGHT) == CardCanPassPosition.RIGHT)
					{
						return true;
					}
				}
			}
			else if (cardUI.cellX + 1 == point.x && cardUI.cellY == point.y)
			{
				if ((cardUI.passPosition & CardCanPassPosition.RIGHT) == CardCanPassPosition.RIGHT)
				{

					if ((card.passPosition & CardCanPassPosition.LEFT) == CardCanPassPosition.LEFT)
					{
						return true;
					}
				}
			}
			else if (cardUI.cellX == point.x && cardUI.cellY + 1 == point.y)
			{
				if ((cardUI.passPosition & CardCanPassPosition.BOTTOM) == CardCanPassPosition.BOTTOM)
				{

					if ((card.passPosition & CardCanPassPosition.TOP) == CardCanPassPosition.TOP)
					{
						return true;
					}
				}
			}
			else if (cardUI.cellX == point.x && cardUI.cellY - 1 == point.y)
			{
				if ((cardUI.passPosition & CardCanPassPosition.TOP) == CardCanPassPosition.TOP)
				{
					if ((card.passPosition & CardCanPassPosition.BOTTOM) == CardCanPassPosition.BOTTOM)
					{
						return true;
					}
				}
			}
			return false;

		}

		private function _heuristic(node:RoadCardUI, endPoint:Point):Number
		{
			return Math.abs(node.cellX - endPoint.x) * 1 + Math.abs(node.cellY - endPoint.y) * 1;
		}

		/**
		 * 函数名：isOpen
		 * 说明：判断节点node是否在待考察表中
		 * 参数：node
		 * 返回值：是否在待考察表中的布尔值
		 */
		private function isOpen(node:RoadCardUI):Boolean
		{
			return _open.indexOf(node) != -1;
		}

		/**
		 * 函数名：isClosed
		 * 说明：判断节点node是否在已考察表中
		 * 参数：node
		 * 返回值：是否在已考察表中的布尔值
		 */
		private function isClosed(node:RoadCardUI):Boolean
		{
			return _closed.indexOf(node) != -1;
		}

		/**
		 * 是否已经到达终点
		 *
		 * -1表示没有终点，1表示上面，2表示中间，3表示下面
		 */
		public function reached():int
		{
			if (getCardByPosition(8, 1) || getCardByPosition(8, 3) || getCardByPosition(7, 4) || getCardByPosition(7, 0) || getCardByPosition(7, 2))
			{
				if (!end1.isknown && search(end1, new Point(8, 0))) //最上面的点
				{
					return 1;
				}
				if (!end2.isknown && search(end2, new Point(8, 2))) //中间的点
				{
					return 2;
				}
				if (!end3.isknown && search(end3, new Point(8, 4))) //下面的点
				{
					return 3;
				}

			}

			return -1;
		}

		/**
		 * 以后可以考虑把a*算法专门提出来
		 * */
		public function search(card:RoadCard, endPoint:Point):Boolean
		{
			initSearch();

			var startPoint:Point = new Point(0, 2);

			//开始寻路算法,起始点node设为_startNode);
			trace("开始寻路：")
			var node:RoadCardUI = getCardByPosition(startPoint.x, startPoint.y);
			trace("node节点设为：" + node);
			while (!isReachPoint(node, card, endPoint)) //node != _endNode)
			{
				//取以node节点为中心，其四周的8个节点
				var startX:int = Math.max(0, node.cellX - 1);
				var endX:int = Math.min(9 - 1, node.cellX + 1);
				var startY:int = Math.max(0, node.cellY - 1);
				var endY:int = Math.min(5 - 1, node.cellY + 1);

				//对四周8个节点每一个做循环操作
				for (var i:int = startX; i <= endX; i++)
				{
					for (var j:int = startY; j <= endY; j++)
					{
						var test:RoadCardUI = getCardByPosition(i, j);
						//当test节点为当前节点，不可通过或其对角的节点不可通过时结束当前循环
						trace("test节点设为：" + test);
						//判断是否可以达到这个节点
						if (null == test || test == node) //|| !test.walkable || !getCardByPosition(node.cellX, test.cellY).walkable || !getCardByPosition(test.cellX, node.cellY).walkable)
						{
							continue;
						}
						/**
						 * 不考虑对角线
						 * */
						if (!((node.cellX == test.cellX) || (node.cellY == test.cellY)))
						{
							continue; //cost = _diagCost;
						}

						/**
						 * 是否可走
						 * */
						if (!test.walkable || !node.walkable)
						{
							continue;
						}

						if (!isReachPoint(node, test.roadCard, new Point(test.cellX, test.cellY)))
						{
							continue;
						}

						//移动到当前节点的代价，挖金矿可以不需要考虑对角线
						var cost:Number = 1; //_straightCost;
						//node节点为对角节点是cost取_diagCost

						//计算当前节点的g、h、f值
						var g:Number = node.g + cost * test.costMultiplier;
						var h:Number = _heuristic(test, endPoint);
						var f:Number = g + h;
						//test节点是否在待考察表或已考察表中
						if (isOpen(test) || isClosed(test))
						{
							if (test.f > f)
							{
								test.f = f;
								test.g = g;
								test.h = h;
								test.parentCard = node;
								trace("test" + test + "的fgh改变，父节点为" + node);
							}
						}
						else
						{
							test.f = f;
							test.g = g;
							test.h = h;
							test.parentCard = node;
							trace("test" + test + "的fgh赋值，父节点为" + node);
							_open.push(test); //test节点添加到待考察表中
							trace("test" + test + "添加进了待考察表。");
						}
					}
				}
				_closed.push(node); //node节点添加到已考察表中
				trace("node" + node + "添加进了已考察表。");
				//待考察表为空，返回无路径
				if (_open.length == 0)
				{
					trace("no path found");
					return false
				}
				trace("待考察表未排序:" + _open);
				//_open.sortOn("f", Array.NUMERIC); //待考察表按节点f值的大小对各节点从新排序
				_open = _open.sort(sortCardUI);
				trace("待考察表排序后:" + _open);
				node = _open.shift(); //将待考察表中第一个节点取出并赋给node
				trace("node设为：" + node + "并将其从待考察表中删除");
			}
			//输出最短路径  node 表示最后一个点
			buildPath(node);
			return true;
		}

		/**
		 * 函数名：buildPath
		 * 说明：输出最短路径，创造一个由最短路径阶段组成的数组
		 * 参数：无
		 * 返回值：无
		 */
		private function buildPath(node:RoadCardUI):void
		{
			_path = new Vector.<RoadCardUI>;
			_path.push(node);
			while (node.cellX != 0 && node.cellY != 2) // != _startNode)
			{
				node = node.parentCard;
				_path.unshift(node);
			}

		}

		private function sortCardUI(first:RoadCardUI, second:RoadCardUI):Number
		{
			if (first.f < second.f)
			{
				return -1;
			}
			else if (first.f > second.f)
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}

		/**
		 * 表示某卡片在地图上移动,返回值表示能否放下
		 * */
		public function cardMoveOnMap(card:CardUI):Point
		{
			var cx:Number = card.x - this.x;
			var cy:Number = card.y - this.y;

			var result:Point;

			if (cy > 0 && cx > 0 && cy < this.height && cx < this.width) //检测已经碰撞
			{
				validateArea.visible = true;
				var position:Point = getPositionByXY(cx, cy);

				//var overCard:RoadCardUI = getCardByPosition(position.x, position.y);

				var canPlace1:Boolean = canPlace(card.card, position.x, position.y);
				if (!canPlace1)
				{
					validateArea.selected = false;
				}
				else
				{
					validateArea.selected = true;
					result = position;
				}

				validateArea.x = position.x * CardUI.WIDTH;
				validateArea.y = position.y * CardUI.HEIGHT;
			}
			else
			{
				hideValidateArea();
			}
			return result;
		}

		public function hideValidateArea():void
		{
			validateArea.visible = false;
		}

		public function getEndCard(direct:int):EndCardUI
		{
			var result:EndCardUI;
			if (direct == 1)
			{
				result = getCardByPosition(8, 0) as EndCardUI;
			}
			else if (direct == 2)
			{
				result = getCardByPosition(8, 2) as EndCardUI;
			}
			else
			{
				result = getCardByPosition(8, 4) as EndCardUI;
			}
			return result;
		}

		/**
		 * 用于初始化四张默认卡片
		 * */
		public function initData():void
		{
			var startCard:RoadCard = new RoadCard(GoldCardType.START);
			startCard.passPosition = CardCanPassPosition.ALL;
			setCardPosition(startCard, 0, 2);

			end1 = new EndCard(GoldCardType.END_DUMP);
			end2 = new EndCard(GoldCardType.END_DUMP);
			end3 = new EndCard(GoldCardType.END_DUMP);

//			var endUI1:EndCardUI = new EndCardUI(end1);
//			var endUI2:EndCardUI = new EndCardUI(end2);
//			var endUI3:EndCardUI = new EndCardUI(end3);

			setCardPosition(end1, 8, 0);
			setCardPosition(end2, 8, 2);
			setCardPosition(end3, 8, 4);

		}

		public function removeCard(x:int, y:int):void
		{
			var cardUI:CardUI = getCardByPosition(x, y);
			if (cardUI)
			{
				cards[x * 5 + y] = null;
				removeChild(cardUI, true);
			}
		}

	}
}
